package thinkingInJava.concurrency;
// page 763 活动对象(另外一种多线程模型，用消息队列来实现)
//: concurrency/ActiveObjectDemo.java
// Can only pass constants, immutables, "disconnected
// objects," or other active objects as arguments
// to asynch methods.
import java.util.concurrent.*;
import java.util.*;
import static thinkingInJava.YTool.YPrint.*;

public class ActiveObjectDemo {
	private ExecutorService ex =
			Executors.newSingleThreadExecutor(); // 单线程保证任务一个一个地进行
	private Random rand = new Random(47);
	// Insert a random delay to produce the effect
	// of a calculation time:
	private void pause(int factor) {
		try {
			TimeUnit.MILLISECONDS.sleep(
					100 + rand.nextInt(factor));
		} catch(InterruptedException e) {
			print("sleep() interrupted");
		}
	}
	public Future<Integer>
	calculateInt(final int x, final int y) {
		return ex.submit(new Callable<Integer>() {
			public Integer call() {
				print("starting " + x + " + " + y);
				pause(500);
				return x + y;
			}
		});
	}
	public Future<Float>
	calculateFloat(final float x, final float y) {
		return ex.submit(new Callable<Float>() {
			public Float call() {
				print("starting " + x + " + " + y);
				pause(2000);
				return x + y;
			}
		});
	}
	public void shutdown() { ex.shutdown(); }
	public static void main(String[] args) {
		ActiveObjectDemo d1 = new ActiveObjectDemo();
		// Prevents ConcurrentModificationException:
		List<Future<?>> results =
				new CopyOnWriteArrayList<Future<?>>();
		for(float f = 0.0f; f < 1.0f; f += 0.2f)
			results.add(d1.calculateFloat(f, f));
		for(int i = 0; i < 5; i++)
			results.add(d1.calculateInt(i, i));
		print("All asynch calls made");
		while(results.size() > 0) {
			for(Future<?> f : results)
				if(f.isDone()) {
					try {
						print(f.get());
					} catch(Exception e) {
						throw new RuntimeException(e);
					}
					results.remove(f);
				}
		}
		d1.shutdown();
	}
} /* Output: (85% match)
All asynch calls made
starting 0.0 + 0.0
starting 0.2 + 0.2
0.0
starting 0.4 + 0.4
0.4
starting 0.6 + 0.6
0.8
starting 0.8 + 0.8
1.2
starting 0 + 0
1.6
starting 1 + 1
0
starting 2 + 2
2
starting 3 + 3
4
starting 4 + 4
6
8
 *///:~
